package com.zhentao.engine.impl;

import com.zhentao.engine.RuleEngine;
import com.zhentao.enums.RuleExecuteStatusEnum;
import com.zhentao.pojo.ParamRule;
import com.zhentao.vo.RuleExecuteResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Spring EL表达式规则引擎
 * @author zhentao
 * @date 2024-12-19
 */
@Slf4j
@Component
public class SpELRuleEngine implements RuleEngine {

    private final ExpressionParser parser = new SpelExpressionParser();

    @Override
    public RuleExecuteResultVO executeRule(ParamRule rule, Map<String, Object> inputData, Map<String, Object> context) {
        RuleExecuteResultVO result = new RuleExecuteResultVO();
        Date startTime = new Date();
        
        try {
            // 准备执行上下文
            StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
            
            // 注入输入数据
            if (inputData != null) {
                for (Map.Entry<String, Object> entry : inputData.entrySet()) {
                    evaluationContext.setVariable(entry.getKey(), entry.getValue());
                }
            }
            
            // 注入上下文数据
            if (context != null) {
                for (Map.Entry<String, Object> entry : context.entrySet()) {
                    evaluationContext.setVariable(entry.getKey(), entry.getValue());
                }
            }
            
            // 注入常用工具类
            evaluationContext.setVariable("Math", Math.class);
            evaluationContext.setVariable("String", String.class);
            evaluationContext.setVariable("System", System.class);
            
            String expression = rule.getConditionExpression();
            if (expression == null || expression.trim().isEmpty()) {
                result.setStatus(RuleExecuteStatusEnum.PARAM_ERROR.getCode());
                result.setMessage("规则表达式为空");
                return result;
            }
            
            // 解析并执行表达式
            Expression exp = parser.parseExpression(expression);
            Object value = exp.getValue(evaluationContext);
            
            // 处理执行结果
            Map<String, Object> resultData = new HashMap<>();
            resultData.put("result", value);
            resultData.put("expression", expression);
            
            result.setStatus(RuleExecuteStatusEnum.SUCCESS.getCode());
            result.setMessage("规则执行成功");
            result.setResultData(resultData);
            
            log.debug("SpEL规则执行成功: {} -> {}", expression, value);
            
        } catch (Exception e) {
            result.setStatus(RuleExecuteStatusEnum.ERROR.getCode());
            result.setMessage("规则执行失败: " + e.getMessage());
            result.setErrorDetail(e.toString());
            log.error("SpEL规则执行失败: {}", rule.getRuleCode(), e);
        } finally {
            result.setEndTime(new Date());
            result.setExecutionTime(result.getEndTime().getTime() - startTime.getTime());
        }
        
        return result;
    }

    @Override
    public String validateRuleSyntax(String ruleContent, String engineType) {
        try {
            if (ruleContent == null || ruleContent.trim().isEmpty()) {
                return "规则内容不能为空";
            }
            
            // 尝试解析表达式语法
            parser.parseExpression(ruleContent);
            
            // 基本语法检查通过
            return null;
            
        } catch (Exception e) {
            return "SpEL表达式语法错误: " + e.getMessage();
        }
    }

    @Override
    public String getSupportedEngineType() {
        return "SPEL";
    }

    @Override
    public int getPriority() {
        return 100; // 中等优先级
    }
}
